<?php
/**
 * @package qBase
 * @subpackage model
 *
 */

/**
 * QDbStorageConfig
 * 
 * @package qBase
 * @subpackage model
 */
class QDbStorageConfig extends QObject 
{
	private $map_objects_list;
	/**
	 * Storage
	 *
	 * @var QDbStorage
	 */
	private $storage;
	
	/**
	 * MapInfo
	 *
	 * @var QDbStorageInfo
	 */
	private $map;

	public function __construct(QDbStorageInfo $map, QDbStorage $storage)
	{
		$this->map = $map;
		$this->storage = $storage;
	}

	public function setMapObject($map_name, $object_class, $table)
	{
		$query = new QSqlQuery();
		
		list($db, $table) = $this->splitTableInfo($table);

		$db_table = $this->storage->getFrameTable("MapObjects");
		
		$this->storage->merge($db_table, 
			array("name" => $map_name), 
			array("id_object" => $this->map->getObjectId($object_class), 
				"id_table" => $this->map->getTableId($table, $db), 
				"name" => $map_name), "id");
				
		// update the info
		$this->map->refresh();
	}

	public function removeMapObject($map_name)
	{
		$db_table = $this->storage->getFrameTable("MapObjects");
		$db_table_filter = $this->storage->getFrameTable("MapObjectsFilters");
		$db_table_props = $this->storage->getFrameTable("MapProperties");
		
		$id = $this->map->getMapObjectId($map_name);

		if ($id > 0)
		{
			$this->sqlDelete($db_table_filter, array("id_map_object" => $id));
			$this->sqlDelete($db_table_props, array("id_map_object" => $id));
			$this->sqlDelete($db_table, array("id" => $id));
		}
		else 
			throw new Exception("Unable to get map object id resulted: {$id}");

		// update the info
		$this->map->refresh();
	}
	
	public function setMapObjectFilter($map_name, $field, QSqlQuery $expression)
	{
		list($field_db, $field_table, $field_column) = $this->splitFieldInfo($field);
		
		var_dump($field_db, $field_table, $field_column);
		
		$db_table = $this->storage->getFrameTable("MapObjectsFilters");
		
		// var_dump($map_name);
		$id = $this->map->getMapObjectId($map_name);
		//var_dump($id);
		$id_field = $this->map->getFieldId($field_table, $field_column, $field_db);
		
		$this->storage->merge($db_table, array("id_map_object" => $id, "id_field" => $id_field), 
			array("id_map_object" => $id, "id_field" => $id_field, "expression" => $expression->serialize()), "id");
			
		// update the info
		$this->map->refresh();
	}

	public function removeMapObjectFilter($map_name, $field)
	{
		// id_map_object 	id_field
		list($field_db, $field_table, $field_column) = $this->splitFieldInfo($field);

		$db_table = $this->storage->getFrameTable("MapObjectsFilters");
		$id = $this->map->getMapObjectId($map_name);
		$id_field = $this->map->getFieldId($field_table, $field_column, $field_db);

		$this->sqlDelete($db_table, array("id_map_object" => $id, "id_field" => $id_field));
	}
	
	private function splitTableInfo($table)
	{
		if (!$table)
			throw new Exception("Invalid table name");
		if (is_array($table))
		{
			if (count($table) != 2)
				throw new Exception("Table name must be specified as a string or as array(database, table)");
			else 
				return $table;
		}
		else if (is_string($table))
			return array(null, $table);
		else 
			throw new Exception("Table name must be specified as a string or as array(database, table)");
	}
	
	private function splitFieldInfo($field)
	{
		if ((!is_array($field)) || (count($field) < 2) || (count($field) > 3))
			throw new Exception("The field must be specified as array(table, field) or array(db, table, field)");

		if (count($field) == 3)
			return $field;
		else if (count($field) == 2)
			return array(null, $field[0], $field[1]);
		
		return null;
	}

	private function sqlDelete($table, $columns_values)
	{
		if ((!is_array($columns_values)) || (count($columns_values) < 1))
			throw new Exception("No conditions specified");
		
		$q = QSqlQuery::NewQuery()->delete()->from()->{$table}->where();

		$pos = 0;
		foreach ($columns_values as $column => $value)
		{
			if ($pos > 0)
				$q->and();
			$q->{$column}->eq()->val($value);
			$pos++;
		}
	
		$q->executeQuery($this->storage->getConnection());
	}
}

?>